/*
* Copyright (c) 2017 Zhangyujie (Tocy)

* This file is part of PlayerDemo project.
*/

#ifndef AUDIO_PLAY_HEADER_FILE_INCLUDE_201703
#define AUDIO_PLAY_HEADER_FILE_INCLUDE_201703

#include <stdint.h>
#include "SDL.h"

class AudioPlayer
{
public:
    enum
    {
        S16 = AUDIO_S16,
        S8 = AUDIO_S8,
        U8 = AUDIO_U8,
    };
    struct AudioSpec
    {
        uint8_t channels;
        uint8_t byte_per_sample;
        uint16_t reserved;
        uint32_t format;
        uint32_t freq;
        // default channels: 2 sample format: S16 sample rate: 48k
        AudioSpec(uint8_t ch=2, uint32_t sample_fmt=S16, uint32_t sample_rate=48000);

        uint8_t get_sample_byte();
        bool operator ==(const AudioSpec & rhs) const;
        bool operator !=(const AudioSpec & rhs) const;
    };

public:
    AudioPlayer();
    ~AudioPlayer();

    bool init();
    void uninit();
    bool play(uint8_t * pcm, int pcm_size, AudioSpec & in_spec);

private:
    enum
    {
        INVALID_AUDIO_DEVICE_ID = 0,
    };
    bool open_device();
    void close_device();

    bool alloc_data_buff();
    void free_data_buff();

    int fill_audio_buff(uint8_t * stream, int size);
    static void sdl_audio_callback(void* userdata, Uint8* stream, int len);
private:
    SDL_AudioDeviceID m_device;
    AudioSpec m_spec;

    uint8_t * m_audio_buff;
    uint32_t m_buff_size;
    uint32_t m_write_pos;
    SDL_mutex * m_mutex;
    bool m_stopped;
};

#endif // #ifndef AUDIO_PLAY_HEADER_FILE_INCLUDE_201703